package com.service.http.okhttp;

import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;


/**
 * 描述：
 * 去除okhttp3的ssl认证
 * @author xianggj
 * @Date 2021/8/30 14:27
 **/
public class OkHttpFactory {


    private OkHttpFactory() {
    }

    public static OkHttpClient getInstance(){
        return OkHttpFactory.Singleton.INSTANCE.getInstance();
    }


    /**
     * 单例枚举
     */
    private static enum Singleton{

        INSTANCE;

        private OkHttpClient singleton;

        /**
         * JVM会保证此方法绝对只调用一次
         */
        private Singleton(){
            singleton = okHttpClient();
        }

        public OkHttpClient getInstance(){
            return singleton;
        }

        /**
         * 绕过ssl 验证
         * @return
         * @see [类、类#方法、类#成员]
         */
        public X509TrustManager x509TrustManager() {
            return new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                }
                @Override
                public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                }
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            };
        }

        public SSLSocketFactory sslSocketFactory() {

            try {
                //信任任何链接
                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());
                return sslContext.getSocketFactory();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }
            return null;
        }
        /**
         * Create a new connection pool with tuning parameters appropriate for a single-user application.
         * The tuning parameters in this pool are subject to change in future OkHttp releases. Currently
         */
        public ConnectionPool pool() {
            return new ConnectionPool(200, 5, TimeUnit.MINUTES);
        }

        public OkHttpClient okHttpClient() {
            return new OkHttpClient.Builder()
                    .sslSocketFactory(sslSocketFactory(), x509TrustManager())
                    .retryOnConnectionFailure(false)
                    .connectionPool(pool())
                    .connectTimeout(60L, TimeUnit.SECONDS)
                    .readTimeout(60L, TimeUnit.SECONDS)
                    .build();
        }
    }
}
